科研星球

如何用R绘制桑基图

桑基图(Sankey Diagram)是一种显示流量数据的可视化图形,在桑基图中,实体(nodes)由矩形或文本表示,实体之间的连接用箭头或弧线表示,箭头或弧线的宽度与流动的重要性或某种数值成比例。

桑基图是一种特定类型的流型图,其中箭头的宽度与流量成比例显示,桑基图将视觉重点放在数据的流动,有助于确定哪个部分对整体流量有主要贡献

1. 桑基图的历史

桑基图是爱尔兰船长马修亨利菲内亚斯·里尔桑基,于1898年第一次正式使用,船长使用这种图形显示了蒸汽发动机能量效率的变化。

尽管最初的桑基图表仅用于显示一种类型的流(例如蒸汽),但为不同类型的流使用颜色可以为桑基图增加更多的可能性。

最著名的"桑基图"之一是Charles Minard绘制的1812年拿破仑俄国战役地图,这幅图将桑基图叠加在地理地图上,这幅图创建于1869年,因此实际上早于1898年的第一幅正式桑基图。

2. 绘制基础桑基图

桑基图描述了数据之间的流动,绘制桑基图的时候,输入的数据可以有两种不同的数据格式,分别为连接数据框和关联矩阵。

连接数据框包含三列,分别表示连接的起点和终点以及连接的权重。

关联矩阵的行和列分别表示连接,矩阵中的值表示权重,关联矩阵是一个方阵。

连接数据框在数据中逐个列出所有连接,通常数据中有一个source和一个target列,可以添加第三列,为每个连接提供更多信息,例如流的值。

下面的代码构建一个连接数据框并将其表示为Sankey图,如图8.9所示。

2.1 加载包

install.packages("tidyverse"# 安装包
install.packages("networkD3"# 安装包
library(tidyverse) # 加载包 
library(networkD3) 

2.2 创建数据框

首先创建一个数据集links,这个数据集包含三个变量,分别为source,target和value。

source 表示连接的起点,target表示连接中的终点。

links <- data.frame( 
  source=c("group_A","group_A""group_B""group_C""group_C""group_E"), 
  target=c("group_C","group_D""group_E""group_F""group_G""group_H"), 
  value=c(2,32313) ) 

2.3 创建一个关于节点的数据框

创建一个nodes数据集,这个数据集记录了所有连接节点的名称。

nodes <- data.frame( 
  name=c(as.character(links$source), 
         as.character(links$target)) %>% unique() 

nodes %>% head(3
##      name
## 1 group_A 
## 2 group_B 
## 3 group_C 

在数据集links中生成两个新的变量IDsource和IDtarget,这两个变量分别表示对应的source变量和target变量的值在nodes变量中的位置。

# 对于networkD3,必须使用id提供连接,而不是像在links数据集中那样使用实名。所以我们需要重新格式化它。
links$IDsource <- match(links$source, nodes$name)-1 
links$IDtarget <- match(links$target, nodes$name)-1 
links %>% head(3
##    source    target  value IDsource IDtarget 
## 1 group_A   group_C    2     0        2 
## 2 group_A   group_D    3     0        4 
## 3 group_B   group_E    2     1        3 

举一个例子,在links数据集的输出结果中可以看到,第一行中source变量对应的值为group_A,对应IDsource变量的值为0。

从nodes的输出结果中可以看到,group_A排在第一个,因此IDsource的值则就等于1-1=0。第一行target变量的值为group_C,在nodes中的位置为第三个,因此Idtarget对应的值为3-1=2。

2.4 绘制图形

数据准备好之后,使用sankeyNetwork函数绘制桑基图。代码中设置参数links=links,Nodes=nodes,Nodes和links是两个基本参数。

Souce参数表示数据中的起点,指定此参数为IDsource变量。
Target参数设定为IDtarget变量。
Value参数表示连接的值,设置为value变量。
NodeID参数用于指定所有节点的名称,设置为变量name。

p <- sankeyNetwork(Links = links, Nodes = nodes, 
                   Source = "IDsource", Target = "IDtarget"
                   Value = "value", NodeID = "name"


0.png

图 8.9 桑基图


运行代码,即可绘制出桑基图。如果数据集是关联矩阵,则需要先转换数据集,然后重新使用上面的代码绘制图形。

需要注意的是,流量相关的数据都可以使用桑基图进行绘制,例如网络浏览相关的数据,桑基图可以来分析网页中页面跳转的情况,使用桑基图可以很清楚的显示出网络流量在不同页面的变化。

在绘制桑基图的时候,有一些注意事项。

  • 首先桑基图节点的位置非常重要
  • 另外桑基图的节点不能过多,太多的节点会使得图形过于混乱,难以理解,因此建议删除掉大多数不重要的弱连接。


相关推荐:
没有账号?